<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>招聘市场技能需求感知系统</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/element-ui@2.15.14/lib/theme-chalk/index.css">
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/element-ui@2.15.14/lib/index.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/echarts-wordcloud@2/dist/echarts-wordcloud.min.js"></script>
    <style>
        body {
            font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;
            margin: 0;
            padding: 0;
            background-color: #f5f7fa;
        }
        .app-container {
            padding: 20px;
        }
        .header {
            background-color: #409EFF;
            color: white;
            padding: 15px 20px;
            margin-bottom: 20px;
            border-radius: 4px;
            box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        .search-box {
            margin-bottom: 20px;
            background-color: white;
            padding: 20px;
            border-radius: 4px;
            box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
        }
        .chart-container {
            background-color: white;
            padding: 20px;
            margin-bottom: 20px;
            border-radius: 4px;
            box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
        }
        .chart {
            height: 400px;
            width: 100%;
        }
        .loading {
            text-align: center;
            margin: 20px 0;
        }
        .el-row {
            margin-bottom: 20px;
        }
        h2 {
            color: #409EFF;
            margin-top: 0;
        }
        .header-right {
            display: flex;
            align-items: center;
        }
        .header-right .el-button {
            margin-left: 10px;
        }
        .search-examples {
            margin-top: 10px;
            color: #909399;
            font-size: 12px;
        }
        .search-examples span {
            cursor: pointer;
            margin-right: 10px;
            color: #409EFF;
        }
        .search-examples span:hover {
            text-decoration: underline;
        }
        .job-stat-cards {
            margin-bottom: 20px;
        }
        .stat-card {
            text-align: center;
            padding: 20px;
        }
        .stat-card .number {
            font-size: 24px;
            font-weight: bold;
            color: #409EFF;
        }
        .stat-card .title {
            color: #909399;
            margin-top: 5px;
        }
        .footer {
            text-align: center;
            padding: 20px;
            color: #909399;
            font-size: 14px;
        }
        .chart-help {
            position: absolute;
            top: 20px;
            right: 20px;
            color: #909399;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <div id="app" class="app-container">
        <div class="header">
            <h1>招聘市场技能需求感知系统</h1>
            <div class="header-right">
                <el-button type="primary" plain icon="el-icon-refresh" @click="search">刷新数据</el-button>
                <el-button icon="el-icon-question" @click="showHelp">使用帮助</el-button>
            </div>
        </div>

        <div class="search-box">
            <el-row :gutter="20">
                <el-col :span="8">
                    <el-select v-model="selectedCity" placeholder="请选择城市" style="width: 100%;">
                        <el-option v-for="city in cities" :key="city" :label="city" :value="city"></el-option>
                    </el-select>
                </el-col>
                <el-col :span="12">
                    <el-input v-model="keyword" placeholder="请输入技能关键词" clearable>
                        <template slot="append">
                            <el-tooltip content="示例：java、产品经理、UI设计师、数据分析师等">
                                <i class="el-icon-question"></i>
                            </el-tooltip>
                        </template>
                    </el-input>
                    <div class="search-examples">
                        热门搜索: 
                        <span @click="setKeyword('java')">Java</span>
                        <span @click="setKeyword('产品经理')">产品经理</span>
                        <span @click="setKeyword('UI')">UI设计</span>
                        <span @click="setKeyword('python')">Python</span>
                        <span @click="setKeyword('数据分析')">数据分析</span>
                        <span @click="setKeyword('人工智能')">人工智能</span>
                    </div>
                </el-col>
                <el-col :span="4">
                    <el-button type="primary" @click="search" style="width: 100%;" :loading="loading">
                        <i class="el-icon-search"></i> 搜索
                    </el-button>
                </el-col>
            </el-row>
        </div>

        <el-row :gutter="20" class="job-stat-cards" v-if="dashboardData">
            <el-col :span="8">
                <el-card shadow="hover" class="stat-card">
                    <div class="number">{{ totalJobs }}</div>
                    <div class="title">职位总数</div>
                </el-card>
            </el-col>
            <el-col :span="8">
                <el-card shadow="hover" class="stat-card">
                    <div class="number">{{ averageSalary }}k</div>
                    <div class="title">平均薪资</div>
                </el-card>
            </el-col>
            <el-col :span="8">
                <el-card shadow="hover" class="stat-card">
                    <div class="number">{{ keySkillsCount }}</div>
                    <div class="title">关联技能数</div>
                </el-card>
            </el-col>
        </el-row>

        <el-row :gutter="20" v-loading="loading">
            <el-col :span="12">
                <div class="chart-container" style="position: relative;">
                    <h2>关联技能词云</h2>
                    <el-tooltip content="词云展示了与搜索条件相关的技能，字体大小表示关联度" placement="top">
                        <i class="el-icon-question chart-help"></i>
                    </el-tooltip>
                    <div id="wordcloud-chart" class="chart"></div>
                </div>
            </el-col>
            <el-col :span="12">
                <div class="chart-container" style="position: relative;">
                    <h2>薪资分布饼图</h2>
                    <el-tooltip content="饼图展示了不同薪资范围的职位分布情况" placement="top">
                        <i class="el-icon-question chart-help"></i>
                    </el-tooltip>
                    <div id="salary-chart" class="chart"></div>
                </div>
            </el-col>
        </el-row>

        <el-row>
            <el-col :span="24">
                <div class="chart-container" style="position: relative;">
                    <h2>城市职位数量与平均薪资对比</h2>
                    <el-tooltip content="柱状图展示三个城市的职位数量，折线图展示平均薪资" placement="top">
                        <i class="el-icon-question chart-help"></i>
                    </el-tooltip>
                    <div id="city-comparison-chart" class="chart"></div>
                </div>
            </el-col>
        </el-row>

        <el-dialog
            title="技能画像系统使用帮助"
            :visible.sync="helpVisible"
            width="50%">
            <div>
                <h3>系统功能</h3>
                <p>本系统基于MongoDB数据库构建，提供招聘市场的技能需求分析功能，帮助用户了解当前招聘市场的技能需求状况。</p>
                
                <h3>使用方法</h3>
                <ol>
                    <li>选择城市：从下拉菜单中选择北京、上海或广州</li>
                    <li>输入关键词：可以输入职位名称、技能名称等关键词进行搜索</li>
                    <li>查看数据画像：系统会根据搜索条件生成技能词云、薪资分布和城市对比</li>
                </ol>
                
                <h3>热门搜索推荐</h3>
                <p>可以点击"热门搜索"中的关键词快速开始搜索，例如：Java、产品经理、UI设计等</p>
            </div>
            <span slot="footer" class="dialog-footer">
                <el-button type="primary" @click="helpVisible = false">我知道了</el-button>
            </span>
        </el-dialog>

        <div class="footer">
            基于MongoDB的招聘市场画像系统 | © 2025 高级数据库课程设计
        </div>
    </div>

    <script>
        new Vue({
            el: '#app',
            data() {
                return {
                    cities: ['北京', '上海', '广州'],
                    selectedCity: '北京',
                    keyword: '',
                    loading: false,
                    wordCloudChart: null,
                    salaryChart: null,
                    cityComparisonChart: null,
                    dashboardData: null,
                    helpVisible: false
                };
            },
            computed: {
                totalJobs() {
                    if (!this.dashboardData || !this.dashboardData.cityComparison) return 0;
                    const cityIndex = this.dashboardData.cityComparison.cities.indexOf(this.selectedCity);
                    return cityIndex >= 0 ? this.dashboardData.cityComparison.jobCounts[cityIndex] : 0;
                },
                averageSalary() {
                    if (!this.dashboardData || !this.dashboardData.cityComparison) return 0;
                    const cityIndex = this.dashboardData.cityComparison.cities.indexOf(this.selectedCity);
                    return cityIndex >= 0 ? Math.round(this.dashboardData.cityComparison.avgSalaries[cityIndex]) : 0;
                },
                keySkillsCount() {
                    if (!this.dashboardData || !this.dashboardData.skillsCloud) return 0;
                    return this.dashboardData.skillsCloud.length;
                }
            },
            mounted() {
                this.initCharts();
                this.search();
                // 检查是否是首次访问，如果是则自动显示帮助对话框
                if (!localStorage.getItem('helpShown')) {
                    this.helpVisible = true;
                    localStorage.setItem('helpShown', 'true');
                }
            },
            methods: {
                initCharts() {
                    this.wordCloudChart = echarts.init(document.getElementById('wordcloud-chart'));
                    this.salaryChart = echarts.init(document.getElementById('salary-chart'));
                    this.cityComparisonChart = echarts.init(document.getElementById('city-comparison-chart'));
                    
                    window.addEventListener('resize', () => {
                        this.wordCloudChart.resize();
                        this.salaryChart.resize();
                        this.cityComparisonChart.resize();
                    });
                },
                search() {
                    if (!this.selectedCity) {
                        this.$message.warning('请选择城市');
                        return;
                    }
                    
                    this.loading = true;
                    
                    axios.get('/api/jobs/dashboard', {
                        params: {
                            city: this.selectedCity,
                            keyword: this.keyword || undefined
                        }
                    })
                    .then(response => {
                        this.dashboardData = response.data;
                        this.renderWordCloud();
                        this.renderSalaryPie();
                        this.renderCityComparison();
                    })
                    .catch(error => {
                        console.error('获取数据失败:', error);
                        this.$message.error('获取数据失败，请稍后重试');
                    })
                    .finally(() => {
                        this.loading = false;
                    });
                },
                setKeyword(keyword) {
                    this.keyword = keyword;
                    this.search();
                },
                showHelp() {
                    this.helpVisible = true;
                },
                renderWordCloud() {
                    const data = this.dashboardData.skillsCloud || [];
                    
                    const option = {
                        tooltip: {
                            trigger: 'item',
                            formatter: function(params) {
                                return `${params.name}: ${params.value}`;
                            }
                        },
                        series: [{
                            type: 'wordCloud',
                            shape: 'circle',
                            left: 'center',
                            top: 'center',
                            width: '90%',
                            height: '90%',
                            right: null,
                            bottom: null,
                            sizeRange: [12, 50],
                            rotationRange: [-30, 30],
                            rotationStep: 45,
                            gridSize: 8,
                            drawOutOfBound: false,
                            textStyle: {
                                fontFamily: 'sans-serif',
                                fontWeight: 'bold',
                                color: function () {
                                    return 'rgb(' + [
                                        Math.round(Math.random() * 160 + 30),
                                        Math.round(Math.random() * 160 + 30),
                                        Math.round(Math.random() * 160 + 30)
                                    ].join(',') + ')';
                                }
                            },
                            emphasis: {
                                focus: 'self',
                                textStyle: {
                                    shadowBlur: 10,
                                    shadowColor: '#333'
                                }
                            },
                            data: data
                        }]
                    };
                    
                    this.wordCloudChart.setOption(option);
                },
                renderSalaryPie() {
                    const data = this.dashboardData.salaryDistribution || [];
                    
                    const option = {
                        tooltip: {
                            trigger: 'item',
                            formatter: '{a} <br/>{b}: {c} ({d}%)'
                        },
                        legend: {
                            orient: 'vertical',
                            right: 10,
                            top: 'center',
                            data: data.map(item => item.name)
                        },
                        series: [
                            {
                                name: '薪资分布',
                                type: 'pie',
                                radius: ['40%', '70%'],
                                avoidLabelOverlap: false,
                                itemStyle: {
                                    borderRadius: 10,
                                    borderColor: '#fff',
                                    borderWidth: 2
                                },
                                label: {
                                    show: false,
                                    position: 'center'
                                },
                                emphasis: {
                                    label: {
                                        show: true,
                                        fontSize: '18',
                                        fontWeight: 'bold'
                                    }
                                },
                                labelLine: {
                                    show: false
                                },
                                data: data
                            }
                        ]
                    };
                    
                    this.salaryChart.setOption(option);
                },
                renderCityComparison() {
                    const data = this.dashboardData.cityComparison || { cities: [], jobCounts: [], avgSalaries: [] };
                    
                    const option = {
                        tooltip: {
                            trigger: 'axis',
                            axisPointer: {
                                type: 'shadow'
                            }
                        },
                        legend: {
                            data: ['职位数量', '平均薪资(K)']
                        },
                        grid: {
                            left: '3%',
                            right: '4%',
                            bottom: '3%',
                            containLabel: true
                        },
                        xAxis: [
                            {
                                type: 'category',
                                data: data.cities || [],
                                axisTick: {
                                    alignWithLabel: true
                                }
                            }
                        ],
                        yAxis: [
                            {
                                type: 'value',
                                name: '职位数量',
                                position: 'left',
                                axisLabel: {
                                    formatter: '{value}'
                                }
                            },
                            {
                                type: 'value',
                                name: '平均薪资(K)',
                                position: 'right',
                                axisLabel: {
                                    formatter: '{value}'
                                }
                            }
                        ],
                        series: [
                            {
                                name: '职位数量',
                                type: 'bar',
                                barWidth: '40%',
                                data: data.jobCounts || [],
                                itemStyle: {
                                    color: '#409EFF'
                                }
                            },
                            {
                                name: '平均薪资(K)',
                                type: 'line',
                                yAxisIndex: 1,
                                data: data.avgSalaries || [],
                                symbol: 'circle',
                                symbolSize: 8,
                                lineStyle: {
                                    width: 3
                                },
                                itemStyle: {
                                    color: '#ff7043'
                                }
                            }
                        ]
                    };
                    
                    this.cityComparisonChart.setOption(option);
                }
            }
        });
    </script>
</body>
</html>